import React, { useState, useEffect } from "react";
import { PageContainer, ProCard, ProTable } from "@ant-design/pro-components";
import {
  Button,
  Form,
  Input,
  Upload,
  message,
  Alert,
  Space,
  Dropdown,
  Menu,
  Modal,
  Popconfirm,
  Descriptions,
  Skeleton,
} from "antd";
import {
  DownloadOutlined,
  UploadOutlined,
  PlusOutlined,
  MinusCircleOutlined,
  SaveOutlined,
  MoreOutlined,
  FileTextOutlined,
  InfoCircleOutlined,
  ExclamationCircleOutlined,
} from "@ant-design/icons";
import * as XLSX from "xlsx";

// 定义计算结果的数据类型
interface CalculationResult {
  id: number;
  x: number;
  y: number;
  z: number;
  result: number;
  timestamp: string;
}

// 计算函数 x^2 + y^2 + z^2
const calculate = (x: number, y: number, z: number): number => {
  return x * x + y * y + z * z;
};

// 生成Excel模板
const generateTemplate = (): Blob => {
  const templateData = [
    { x: 1, y: 2, z: 3 },
    { x: 4, y: 5, z: 6 },
  ];

  const ws = XLSX.utils.json_to_sheet(templateData);
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, "计算数据");

  // 添加说明页
  const instructions = [
    { 说明: "请在x、y、z列中填入数值, 不要修改列名" },
    { 说明: "结果列将自动计算 x² + y² + z² 的值" },
    { 说明: "请勿删除第一行标题" },
  ];
  const wsInstructions = XLSX.utils.json_to_sheet(instructions);
  XLSX.utils.book_append_sheet(wb, wsInstructions, "使用说明");

  const excelBuffer = XLSX.write(wb, { bookType: "xlsx", type: "array" });
  return new Blob([excelBuffer], {
    type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  });
};

// 下载Excel模板
const downloadTemplate = () => {
  const blob = generateTemplate();
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = "计算模板.xlsx";
  a.click();
  URL.revokeObjectURL(url);
  message.success("模板下载成功！");
};

// 验证上传的数据
const validateData = (
  data: any[]
): { isValid: boolean; errorMessage?: string } => {
  if (!data || data.length === 0) {
    return { isValid: false, errorMessage: "上传的文件为空！" };
  }

  // 检查是否包含必要的列
  const firstRow = data[0];
  if (
    (!firstRow.x && firstRow.x !== 0) ||
    (!firstRow.y && firstRow.y !== 0) ||
    (!firstRow.z && firstRow.z !== 0)
  ) {
    return {
      isValid: false,
      errorMessage: "上传的文件格式不正确, 缺少必要的列(x, y, z)!",
    };
  }

  // 检查所有行是否有有效数据
  for (let i = 0; i < data.length; i++) {
    const row = data[i];
    if (isNaN(Number(row.x)) || isNaN(Number(row.y)) || isNaN(Number(row.z))) {
      return {
        isValid: false,
        errorMessage: `第 ${i + 1} 行包含无效数据，请确保所有值都是数字！`,
      };
    }
  }

  return { isValid: true };
};

// 处理上传的数据并计算结果
const processData = (data: any[], currentId: number): CalculationResult[] => {
  return data.map((row, index) => ({
    id: currentId + index,
    x: Number(row.x),
    y: Number(row.y),
    z: Number(row.z),
    result: calculate(Number(row.x), Number(row.y), Number(row.z)),
    timestamp: new Date().toISOString(),
  }));
};

// 导出计算结果到Excel
const exportResults = (results: CalculationResult[]) => {
  if (results.length === 0) {
    message.warning("没有数据可导出！");
    return;
  }

  try {
    // 准备导出数据
    const exportData = results.map((result) => ({
      ID: result.id,
      X: result.x,
      Y: result.y,
      Z: result.z,
      计算结果: result.result,
      计算时间: new Date(result.timestamp).toLocaleString(),
    }));

    // 创建工作簿和工作表
    const ws = XLSX.utils.json_to_sheet(exportData);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "计算结果");

    // 生成Excel文件并下载
    const excelBuffer = XLSX.write(wb, { bookType: "xlsx", type: "array" });
    const blob = new Blob([excelBuffer], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    });

    // 创建下载链接
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `计算结果_${new Date().toISOString().slice(0, 10)}.xlsx`;
    a.click();

    // 释放URL对象
    URL.revokeObjectURL(url);

    message.success("导出成功！");
  } catch (error) {
    console.error("导出失败:", error);
    message.error("导出失败，请重试！");
  }
};

export const MathCalculator: React.FC = () => {
  const [results, setResults] = useState<CalculationResult[]>([]);
  const [loading, setLoading] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [form] = Form.useForm();
  const [currentId, setCurrentId] = useState(1);
  const [selectedResult, setSelectedResult] =
    useState<CalculationResult | null>(null);
  const [resultModalVisible, setResultModalVisible] = useState(false);
  const [showEmptyState, setShowEmptyState] = useState(false);

  // 初始化示例数据
  useEffect(() => {
    setLoading(true);
    // 模拟API请求延迟
    setTimeout(() => {
      const mockData = generateMockData();
      setResults(mockData);
      setCurrentId(mockData.length + 1);
      setLoading(false);
      setShowEmptyState(mockData.length === 0);
    }, 500);
  }, []);

  // 生成示例数据
  const generateMockData = (): CalculationResult[] => {
    return [
      {
        id: 1,
        x: 1,
        y: 2,
        z: 3,
        result: calculate(1, 2, 3),
        timestamp: new Date().toISOString(),
      },
      {
        id: 2,
        x: 4,
        y: 5,
        z: 6,
        result: calculate(4, 5, 6),
        timestamp: new Date().toISOString(),
      },
      {
        id: 3,
        x: 7,
        y: 8,
        z: 9,
        result: calculate(7, 8, 9),
        timestamp: new Date().toISOString(),
      },
    ];
  };

  // 处理单个计算
  const handleCalculate = async () => {
    try {
      const values = await form.validateFields();
      const { x, y, z } = values;

      // 验证输入
      if (isNaN(Number(x)) || isNaN(Number(y)) || isNaN(Number(z))) {
        message.error("请输入有效的数字！");
        return;
      }

      const result = calculate(Number(x), Number(y), Number(z));
      const newResult: CalculationResult = {
        id: currentId,
        x: Number(x),
        y: Number(y),
        z: Number(z),
        result,
        timestamp: new Date().toISOString(),
      };

      setResults([...results, newResult]);
      setCurrentId(currentId + 1);
      form.resetFields();

      // 显示成功提示
      message.success("计算成功！结果已添加到表格中");
      setShowEmptyState(false);
    } catch (error) {
      console.error("计算出错:", error);
      message.error("计算过程中发生错误！");
    }
  };

  // 处理Excel文件上传
  const handleUpload = (file: File) => {
    setUploading(true);

    const reader = new FileReader();
    reader.onload = (e) => {
      try {
        const data = new Uint8Array(e.target?.result as ArrayBuffer);
        const workbook = XLSX.read(data, { type: "array" });

        // 获取第一个工作表
        const firstSheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[firstSheetName];

        // 将工作表转换为JSON
        const jsonData = XLSX.utils.sheet_to_json(worksheet);

        // 验证数据格式
        const validationResult = validateData(jsonData);
        if (!validationResult.isValid) {
          message.error(validationResult.errorMessage || "数据验证失败");
          setUploading(false);
          return;
        }

        // 处理数据并计算结果
        const newResults = processData(jsonData, currentId);
        setResults([...results, ...newResults]);
        setCurrentId(currentId + newResults.length);

        message.success(`成功导入 ${newResults.length} 条计算结果！`);
        setShowEmptyState(false);
      } catch (error) {
        console.error("导入文件出错:", error);
        message.error("导入文件格式不正确，请使用下载的模板！");
      } finally {
        setUploading(false);
      }
    };

    reader.readAsArrayBuffer(file);
  };

  // 查看结果详情
  const viewResultDetails = (result: CalculationResult) => {
    setSelectedResult(result);
    setResultModalVisible(true);
  };

  // 关闭结果详情
  const closeResultDetails = () => {
    setResultModalVisible(false);
  };

  // 删除结果
  const deleteResult = (id: number) => {
    setResults(results.filter((r) => r.id !== id));
    if (results.length === 1) {
      setShowEmptyState(true);
    }
  };

  // 列定义
  const columns = [
    {
      title: "ID",
      dataIndex: "id",
      width: 80,
      sorter: (a: any, b: any) => a.id - b.id,
    },
    {
      title: "X",
      dataIndex: "x",
      width: 100,
      sorter: (a: any, b: any) => a.x - b.x,
    },
    {
      title: "Y",
      dataIndex: "y",
      width: 100,
      sorter: (a: any, b: any) => a.y - b.y,
    },
    {
      title: "Z",
      dataIndex: "z",
      width: 100,
      sorter: (a: any, b: any) => a.z - b.z,
    },
    {
      title: "计算结果 (X² + Y² + Z²)",
      dataIndex: "result",
      width: 150,
      sorter: (a: any, b: any) => a.result - b.result,
      render: (text: number) => (
        <span
          style={{
            fontWeight: "bold",
            color: text > 100 ? "#1890ff" : "#52c41a",
          }}
        >
          {text}
        </span>
      ),
    },
    {
      title: "计算时间",
      dataIndex: "timestamp",
      width: 180,
      sorter: (a: any, b: any) =>
        new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),
      render: (text: string) => new Date(text).toLocaleString(),
    },
    {
      title: "操作",
      valueType: "option",
      width: 120,
      render: (_: unknown, record: CalculationResult) => (
        <Space>
          <Button
            icon={<FileTextOutlined />}
            size="small"
            onClick={() => viewResultDetails(record)}
          >
            详情
          </Button>
          <Popconfirm
            title="确定要删除这条记录吗？"
            onConfirm={() => deleteResult(record.id)}
            okText="确定"
            cancelText="取消"
          >
            <Button icon={<MinusCircleOutlined />} size="small" danger>
              删除
            </Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  // 批量操作菜单
  const batchOperationMenu = (
    <Menu>
      <Menu.Item key="download-template" onClick={downloadTemplate}>
        <DownloadOutlined /> 下载计算模板
      </Menu.Item>
      <Menu.Item key="upload-file">
        <Upload
          accept=".xlsx, .xls"
          beforeUpload={(file) => {
            handleUpload(file);
            return false;
          }}
          showUploadList={false}
        >
          <Button
            icon={<UploadOutlined />}
            loading={uploading}
            style={{ width: "100%" }}
          >
            上传计算文件
          </Button>
        </Upload>
      </Menu.Item>
      <Menu.Divider />
      <Menu.Item key="export-results" onClick={() => exportResults(results)}>
        <SaveOutlined /> 导出计算结果
      </Menu.Item>
    </Menu>
  );

  // 自定义空状态
  const emptyState = (
    <div style={{ textAlign: "center", padding: "40px 0" }}>
      <div style={{ fontSize: 36, marginBottom: 16 }}>
        <InfoCircleOutlined style={{ color: "#1890ff" }} />
      </div>
      <p style={{ fontSize: 16, fontWeight: "bold", marginBottom: 8 }}>
        暂无计算结果
      </p>
      <p style={{ color: "#8c8c8c", marginBottom: 24 }}>
        请使用上方表单进行计算或上传Excel文件
      </p>
      <Button
        type="primary"
        icon={<PlusOutlined />}
        onClick={() => {
          const mockData = generateMockData();
          setResults(mockData);
          setCurrentId(mockData.length + 1);
          setShowEmptyState(false);
          message.success("已生成示例数据");
        }}
      >
        生成示例数据
      </Button>
    </div>
  );

  return (
    <PageContainer title="数学计算工具">
      {/* 单个计算区域 */}
      <ProCard title="单个计算">
        <Form
          form={form}
          layout="inline"
          initialValues={{ x: 0, y: 0, z: 0 }}
          style={{ marginBottom: 16 }}
        >
          <Form.Item
            name="x"
            label="X"
            rules={[{ required: true, message: "请输入X的值" }]}
          >
            <Input type="number" placeholder="请输入X的值" />
          </Form.Item>
          <Form.Item
            name="y"
            label="Y"
            rules={[{ required: true, message: "请输入Y的值" }]}
          >
            <Input type="number" placeholder="请输入Y的值" />
          </Form.Item>
          <Form.Item
            name="z"
            label="Z"
            rules={[{ required: true, message: "请输入Z的值" }]}
          >
            <Input type="number" placeholder="请输入Z的值" />
          </Form.Item>
          <Form.Item>
            <Button
              type="primary"
              icon={<PlusOutlined />}
              onClick={handleCalculate}
            >
              计算
            </Button>
          </Form.Item>
        </Form>
      </ProCard>

      {/* 批量操作区域 */}
      <div style={{ marginBottom: 16 }}>
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
          }}
        >
          <div>
            <Dropdown overlay={batchOperationMenu} trigger={["click"]}>
              <Button icon={<MoreOutlined />}>批量操作</Button>
            </Dropdown>
          </div>
          <div>
            <span style={{ fontWeight: "bold" }}>
              总计: {results.length} 条记录
            </span>
          </div>
        </div>
      </div>

      {/* 结果表格 */}
      <ProCard title="计算结果">
        <ProTable
          columns={columns as any}
          dataSource={results}
          loading={loading}
          rowKey="id"
          pagination={{
            pageSize: 10,
            total: results.length,
          }}
          actionRef={React.createRef()}
          scroll={{ x: 800 }}
        />
      </ProCard>

      {/* 结果详情模态框 */}
      <Modal
        title="计算结果详情"
        open={resultModalVisible}
        onCancel={closeResultDetails}
        width={400}
        style={{ padding: 24 }}
      >
        {selectedResult ? (
          <div>
            <Descriptions layout="vertical">
              <Descriptions.Item label="ID">
                {selectedResult.id}
              </Descriptions.Item>
              <Descriptions.Item label="计算公式">
                X² + Y² + Z²
              </Descriptions.Item>
              <Descriptions.Item label="计算结果">
                <span
                  style={{ fontWeight: "bold", color: "#1890ff", fontSize: 24 }}
                >
                  {selectedResult.result}
                </span>
              </Descriptions.Item>
              <Descriptions.Item label="计算时间">
                {new Date(selectedResult.timestamp).toLocaleString()}
              </Descriptions.Item>
            </Descriptions>

            <Descriptions layout="vertical" style={{ marginTop: 16 }}>
              <Descriptions.Item label="X值">
                {selectedResult.x}
              </Descriptions.Item>
              <Descriptions.Item label="Y值">
                {selectedResult.y}
              </Descriptions.Item>
              <Descriptions.Item label="Z值">
                {selectedResult.z}
              </Descriptions.Item>
            </Descriptions>
          </div>
        ) : (
          <Skeleton active />
        )}
      </Modal>
    </PageContainer>
  );
};
